GDI+ is the successor to GDI, the graphics device interface included with earlier versions of Windows.
A graphics device interface, such as GDI+, allows application programmers to display information on a screen or printer without having to be concerned about the details of a particular display device. The application programmer makes calls to the provided functions and those functions in turn make the appropriate calls to specific device drivers. GDI+ insulates the application from the graphics hardware, and it is this insulation that allows developers to create device-independent applications.
Microsoft Windows GDI+ exposes a flat application programming interface (API) that consists of about 600 functions, which are implemented in Gdiplus.dll and declared in Gdiplusflat.h. Microsoft has wrapped these functions with a collection of about 40 C++ classes and the Microsoft Product Support Services will not provide support for code that calls the flat API directly.
The functions in the flat API return a status value that indicates whether the call has succeeded or not.
Documentation MSDN Documentation: GDI+
Microsoft Windows GDI+ exposes a flat application programming interface (API) that consists of about 600 functions, which are implemented in Gdiplus.dll and declared in Gdiplusflat.h.
The functions in the flat API return a value of type GpStatus, identical to the Status enumeration.
#define _WIN32_WINNT &h0602
#INCLUDE ONCE "AfxNova/AfxGdiPlus.bi"
#INCLUDE ONCE "AfxNova/ARGB_Colors.bi"
#INCLUDE ONCE "AfxNova/CGraphCtx.inc"
USING AfxNova
CONST IDC_GRCTX = 1001
DECLARE FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
BYVAL hPrevInstance AS HINSTANCE, _
BYVAL pwszCmdLine AS WSTRING PTR, _
BYVAL nCmdShow AS LONG) AS LONG
END wWinMain(GetModuleHandleW(NULL), NULL, wCOMMAND(), SW_NORMAL)
' // Forward declaration
DECLARE FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
' ========================================================================================
' Put here the example code
' ========================================================================================
SUB Example_XXXX (BYVAL hdc AS HDC)
END SUB
' ========================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
BYVAL hPrevInstance AS HINSTANCE, _
BYVAL pwszCmdLine AS WSTRING PTR, _
BYVAL nCmdShow AS LONG) AS LONG
' // Set process DPI aware
SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE)
' // Enable visual styles without including a manifest file
AfxEnableVisualStyles
' // Create the main window
DIM pWindow AS CWindow = "MyClassName"
' pWindow.CreateOverlapped(NULL, "GDI+ CreateAdjustableArrowCap", @WndProc)
pWindow.Create(NULL, "GDI+ CreateAdjustableArrowCap", @WndProc)
' // Size it by setting the wanted width and height of its client area
pWindow.SetClientSize(400, 250)
' // Center the window
pWindow.Center
' // Add a graphic control
DIM pGraphCtx AS CGraphCtx = CGraphCtx(@pWindow, IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
pGraphCtx.Clear RGB_FLORALWHITE
' // Anchor the control
pWindow.AnchorControl(pGraphCtx.hWindow, AFX_ANCHOR_HEIGHT_WIDTH)
' // Get the memory device context of the graphic control
DIM hdc AS HDC = pGraphCtx.GetMemDc
' // Initialize GDI+
DIM token AS ULONG_PTR = AfxGdipInit
' // Draw the graphics
Example_CreateAdjustableArrowCap(hdc)
' // Displays the window and dispatches the Windows messages
FUNCTION = pWindow.DoEvents(nCmdShow)
' // Shutdown GDI+
AfxGdipShutdown token
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
SELECT CASE uMsg
' // If an application processes this message, it should return zero to continue
' // creation of the window. If the application returns –1, the window is destroyed
' // and the CreateWindowExW function returns a NULL handle.
CASE WM_CREATE
AfxEnableDarkModeForWindow(hwnd)
RETURN 0
' // Theme has changed
CASE WM_THEMECHANGED
AfxEnableDarkModeForWindow(hwnd)
RETURN 0
CASE WM_COMMAND
SELECT CASE CBCTL(wParam, lParam)
CASE IDCANCEL
' // If ESC key pressed, close the application by sending an WM_CLOSE message
IF CBCTLMSG(wParam, lParam) = BN_CLICKED THEN
SendMessageW hwnd, WM_CLOSE, 0, 0
RETURN 0
END IF
END SELECT
CASE WM_DESTROY
' // Ends the application by sending a WM_QUIT message
PostQuitMessage(0)
RETURN 0
END SELECT
' // Default processing of Windows messages
FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
| Name | Description |
|---|---|
| GdiplusStartup | Initializes Microsoft Windows GDI+. |
| GdiplusShutdown | Cleans up resources used by Windows GDI+. |
| GdipAlloc | Allocates memory for GDI+ objects. |
| GdipFree | Frees memory allocated for GDI+ objects. |
| Name | Description |
|---|---|
| AfxGdipInit | Initilizes GDI+. |
| AfxGdipShutdown | Cleans up resources used by Windows GDI+. |
| AfxGdipStatusStr | Returns the description of a GdiPlus status code. |
| ObjectTypeIsValid | Determines whether an element of the ObjectType enumeration represents a valid object type. |
The GdiplusStartup function initializes Microsoft Windows GDI+. Call GdiplusStartup before making any other GDI+ calls, and call GdiplusShutdown when you have finished using GDI+.
FUNCTION GdiplusStartup (BYVAL token AS ULONG_PTR PTR, BYVAL input AS CONST GdiplusStartupInput PTR, _
BYVAL output AS GdiplusStartupOutput PTR) AS GpStatus
| Parameter | Description |
|---|---|
| token | [out] Pointer to a ULONG_PTR that receives a token. Pass the token to GdiplusShutdown when you have finished using GDI+. |
| input | [in] Pointer to a GdiplusStartupInput structure that contains the GDI+ version, a pointer to a debug callback function, a Boolean value that specifies whether to suppress the background thread, and a Boolean value that specifies whether to suppress external image codecs. |
| output | [out] Pointer to a GdiplusStartupOutput structure that receives a pointer to a notification hook function and a pointer to a notification unhook function. If the SuppressBackgroundThread data member of the input parameter is FALSE, then this parameter can be NULL. |
If the function succeeds, it returns Ok, which is an element of the Status enumeration.
If the function fails, it returns one of the other elements of the Status enumeration.
You must call GdiplusStartup before you create any GDI+ objects, and you must delete all of your GDI+ objects before you call GdiplusShutdown.
You can call GdiplusStartup on one thread and call GdiplusShutdown on another thread as long as you delete all of your GDI+ objects (or have them go out of scope) before you call GdiplusShutdown.
Do not call GdiplusStartup or GdiplusShutdown in DllMain or in any function that is called by DllMain. If you want to create a dynamic-link library (DLL) that uses GDI+, you should use one of the following techniques to initialize GDI+:
Warning For info about how to use dynamic data exchange (DDE) with GDI+, see Special CWinApp Services.
The GdiplusShutdown function cleans up resources used by Microsoft Windows GDI+. Each call to GdiplusStartup should be paired with a call to GdiplusShutdown.
The GdiplusShutdown function cleans up resources used by Windows GDI+. Each call to GdiplusStartup should be paired with a call to GdiplusShutdown.
SUB GdiplusShutdown (BYVAL token AS ULONG_PTR)
| Parameter | Description |
|---|---|
| token | [in] Token returned by a previous call to GdiplusStartup. |
You must call GdiplusStartup before you create any GDI+ objects, and you must delete all of your GDI+ objects before you call GdiplusShutdown.
Allocates memory for GDI+ objects.
FUNCTION GdipAlloc (BYVAL size AS size_t) AS ANY PTR
| Parameter | Description |
|---|---|
| size | [in] [in] Number of bytes to be allocated. |
If the function succeeds, the return value is a pointer to the allocated memory block.
If the function fails, then return value is NULL.
Frees memory allocated for GDI+ objects.
SUB GdipFree (BYVAL ptr AS ANY PTR)
| Parameter | Description |
|---|---|
| ptr | [in] Pointer to the memory block to free. |
The ObjectTypeIsValid function determines whether an element of the ObjectType enumeration represents a valid object type.
FUNCTION ObjectTypeIsValid (BYVAL type_ as ObjectType) AS BOOLEAN
FUNCTION = -((type_ >= ObjectTypeMin) AND (type_ <= ObjectTypeMax))
END FUNCTION
| Parameter | Description |
|---|---|
| type | [in] Element of the ObjectType enumeration to be tested. |
If objectType is equal to ObjectTypeInvalid, this function returns FALSE.
If objectType is equal to any other element of the ObjectType enumeration, this function returns TRUE.
Initilizes GDI+
FUNCTION AfxGdipInit () AS ULONG_PTR
You must call AfxGdipInit before you create any GDI+ objects, and you must delete all of your GDI+ objects (or have them go out of scope) before you call AfxGdipShutdown.
You can call AfxGdipIni” on one thread and call AfxGdipShutdown”” on another thread as long as you delete all of your GDI+ objects (or have them go out of scope) before you call AfxGdipShutdown**.
Do not call AfxGdipIni or AfxGdipShutdown in DllMain or in any function that is called by DllMain. If you want to create a DLL that uses GDI+, you should use one of the following techniques to initialize GDI+:
Cleans up resources used by Windows GDI+. Each call to AfxGdipInit should be paired with a call to AfxGdipShutdown.
FUNCTION AfxGdipShutdown (BYVAL token AS ULONG_PTR)
| Parameter | Description |
|---|---|
| token | [in] Token returned by a previous call to AfxGdipInit. |
You must call AfxGdipInit before you create any GDI+ objects, and you must delete all of your GDI+ objects (or have them go out of scope) before you call AfxGdipShutdown.
Returns the description of a GdiPlus status code.
PRIVATE FUNCTION AfxGdipStatusStr (BYVAL status AS GpStatus) AS DWSTRING
DIM wszMsg AS WSTRING * 260 = "Unknown"
SELECT CASE status
CASE Ok : wszMsg = "Ok"
CASE GenericError : wszMsg = "Generic error"
CASE InvalidParameter : wszMsg = "Invalid parameter"
CASE OutOfMemory : wszMsg = "Out of memory"
CASE ObjectBusy : wszMsg = "Object busy"
CASE InsufficientBuffer : wszMsg = "Insufficient buffer"
CASE NotImplemented : wszMsg = "Not implemented"
CASE Win32Error : wszMsg = "Win 32 error"
CASE WrongState : wszMsg = "Wrong state"
CASE Aborted : wszMsg = "Aborted"
CASE FileNotFound : wszMsg = "File not found"
CASE ValueOverflow : wszMsg = "Value overflow"
CASE AccessDenied : wszMsg = "Access denied"
CASE UnknownImageFormat : wszMsg = "Unknown image format"
CASE FontFamilyNotFound : wszMsg = "Font family not found"
CASE FontStyleNotFound : wszMsg = "Font style not found"
CASE NotTrueTypeFont : wszMsg = "Not TrueType font"
CASE UnsupportedGdiplusVersion : wszMsg = "Unsupported GdiPlus version"
CASE GdiplusNotInitialized : wszMsg = "GdiPlus not initialized"
CASE PropertyNotFound : wszMsg = "Property not found"
CASE PropertyNotSupported : wszMsg = "Property not supported"
' #IF (GDIPVER >= &H0110)
' CASE ProfileNotFound : wszMsg = "Profile not found"
' #ENDIF ' //(GDIPVER >= &H0110)
END SELECT
RETURN wszMsg
END FUNCTION